﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericStateMachine
{
    // internal helper class

    internal class ReentrancyBlocker
    {
        private class Scope : IDisposable
        {
            private readonly ReentrancyBlocker parent;
            private bool disposed;

            public Scope(ReentrancyBlocker parent)
            {
                this.parent = parent;
                this.disposed = false;

                parent.busyCount++;
            }

            public void Dispose()
            {
                if (disposed)
                {
                    throw new ObjectDisposedException("ReentrancyBlocker.Scope");
                }
                disposed = true;

                parent.busyCount--;
            }
        }

        private int busyCount;

        public ReentrancyBlocker()
        {
            busyCount = 0;
        }

        public bool IsBusy
        {
            get { return busyCount > 0; }
        }

        public IDisposable CreateScope()
        {
            if (IsBusy)
            {
                throw new InvalidOperationException("ReentrancyBlocker is busy.");
            }

            var ret = new Scope(this);
            return ret;
        }
    }
}
